package com.richpay.landiprintdemo.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Environment;
import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

public class SignBitmapUtil {
    //	static {
//		initImagePath();
//	}
    private static String imageFolder;

    private SignBitmapUtil() {
    }

    public static void initImagePath(Context context) {

        if (imageFolder == null) {
            initImageFolder(context);
        }

        File file = new File(imageFolder);
        if (!file.exists()) {
            file.mkdir();
        }

    }

    private static void initImageFolder(Context context) {
        imageFolder = Environment.getExternalStorageDirectory() + "/RichPay/demo";
    }

    private static String getApplicationName(Context context) {
        String packageName = context.getPackageName();
        String[] packagePath = packageName.split("\\.");
        if (packagePath != null && packagePath.length > 0) {
            return packagePath[packagePath.length - 1];
        }
        return null;
    }

    public static String getImagePath() {
        return imageFolder + "/name.bmp";
    }


    public static byte[] generateByte(String imageData) {

        if (imageData == null) {
            return null;
        }
        return Base64.decode(imageData, Base64.DEFAULT);
    }

    // 从画板图像生成用于压缩的数据，与save1bBmpx生成的数据相反，否则上送的数据、用压缩数据解压出来的图片都是反的
    public static ByteArrayOutputStream convert1BitBmp(Bitmap bitmap) {
        if (bitmap == null) {
            throw new IllegalArgumentException();
        }

        // 位图大小
        int nBmpWidth = bitmap.getWidth();
        int nBmpHeight = bitmap.getHeight();
        // 图像数据大小
        int wid = nBmpWidth % 32;
        if (wid > 0) {
            wid = 32 - nBmpWidth % 32;
        }
        wid += nBmpWidth;// 宽度必须是4的倍数，位图数据是以4个字节为一组来处理的。

        int bufferSize = nBmpHeight * wid / 8;
        ByteArrayOutputStream os;
        try {
            // 存储文件名
            os = new ByteArrayOutputStream();
            // bmp文件头
            int bfType = 0x4d42;
            long bfSize = 14 + 40 + 2 * 4 + bufferSize;
            int bfReserved1 = 0;
            int bfReserved2 = 0;
            long bfOffBits = 14 + 40 + 2 * 4;
            // 保存bmp文件头
            writeWord(os, bfType);
            writeDword(os, bfSize);
            writeWord(os, bfReserved1);
            writeWord(os, bfReserved2);
            writeDword(os, bfOffBits);
            // bmp信息头
            long biSize = 40L;
            long biWidth = nBmpWidth;
            long biHeight = nBmpHeight;
            int biPlanes = 1;
            int biBitCount = 1;
            long biCompression = 0L;
            long biSizeImage = bufferSize;
            long biXpelsPerMeter = 0L;
            long biYPelsPerMeter = 0L;
            long biClrUsed = 0L;
            long biClrImportant = 2L;
            // 保存bmp信息头
            writeDword(os, biSize);
            writeLong(os, biWidth);
            writeLong(os, biHeight);
            writeWord(os, biPlanes);
            writeWord(os, biBitCount);
            writeDword(os, biCompression);
            writeDword(os, biSizeImage);
            writeLong(os, biXpelsPerMeter);
            writeLong(os, biYPelsPerMeter);
            writeDword(os, biClrUsed);
            writeDword(os, biClrImportant);

            // 调色板
            byte rgbBlue0 = 0x0;
            byte rgbGreen0 = 0x0;
            byte rgbRed0 = 0x0;
            byte rgbReserved0 = 0x0;
            byte rgbBlue1 = (byte) 0xff;
            byte rgbGreen1 = (byte) 0xff;
            byte rgbRed1 = (byte) 0xff;
            byte rgbReserved1 = (byte) 0x00;
            // 保存调色板
            writeByte(os, rgbBlue0);
            writeByte(os, rgbGreen0);
            writeByte(os, rgbRed0);
            writeByte(os, rgbReserved0);
            writeByte(os, rgbBlue1);
            writeByte(os, rgbGreen1);
            writeByte(os, rgbRed1);
            writeByte(os, rgbReserved1);

            // 像素扫描
            byte bmpData[] = new byte[bufferSize];
            for (int nCol = 0; nCol < nBmpHeight; ++nCol) {
                for (int wRow = 0; wRow < nBmpWidth; ) {
                    int color0 = getPixel(bitmap, wRow++, nCol);

                    int color1 = getPixel(bitmap, wRow++, nCol);

                    int color2 = getPixel(bitmap, wRow++, nCol);

                    int color3 = getPixel(bitmap, wRow++, nCol);

                    int color4 = getPixel(bitmap, wRow++, nCol);

                    int color5 = getPixel(bitmap, wRow++, nCol);

                    int color6 = getPixel(bitmap, wRow++, nCol);

                    int color7 = getPixel(bitmap, wRow, nCol);

                    // wRow++必须写在下面这句
                    bmpData[nCol * (wid / 8) + wRow++ / 8] = (byte) ((color0 << 7)
                            | (color1 << 6)
                            | (color2 << 5)
                            | (color3 << 4)
                            | (color4 << 3) | (color5 << 2) | (color6 << 1) | (color7));

                }
            }

            os.write(bmpData);
            os.flush();
            return os;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static int getPixel(Bitmap bitmap, int x, int y) {
        if (x < bitmap.getWidth() && y < bitmap.getHeight()) {
            int clr = bitmap.getPixel(x, y);
            return (Color.blue(clr) + Color.green(clr) + Color
                    .red(clr)) / 3 / 255 ^ 1;
        } else {
            return 1;
        }
    }


    private static void writeByte(OutputStream stream, int value)
            throws IOException {
        byte[] b = new byte[1];
        b[0] = (byte) (value & 0xff);
        stream.write(b);
    }

    private static void writeWord(OutputStream stream, int value)
            throws IOException {
        byte[] b = new byte[2];
        b[0] = (byte) (value & 0xff);
        b[1] = (byte) (value >> 8 & 0xff);
        stream.write(b);
    }

    private static void writeDword(OutputStream stream, long value)
            throws IOException {
        byte[] b = new byte[4];
        b[0] = (byte) (value & 0xff);
        b[1] = (byte) (value >> 8 & 0xff);
        b[2] = (byte) (value >> 16 & 0xff);
        b[3] = (byte) (value >> 24 & 0xff);
        stream.write(b);
    }

    private static void writeLong(OutputStream stream, long value)
            throws IOException {
        byte[] b = new byte[4];
        b[0] = (byte) (value & 0xff);
        b[1] = (byte) (value >> 8 & 0xff);
        b[2] = (byte) (value >> 16 & 0xff);
        b[3] = (byte) (value >> 24 & 0xff);
        stream.write(b);
    }
}
